package com.zhaojun.netty.helloworld;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

import java.nio.charset.Charset;

/**
 * Created by asus on 2017/9/24.
 */
public class Server {

    public static void main(String[] args) {
        EventLoopGroup bossGroup=new NioEventLoopGroup();//设置主线程 主要用来接收客户端请求并分发给worker线程
        EventLoopGroup workerGroup=new NioEventLoopGroup();//设置工作线程  主要用来处理主线程分发的网络任务
        ServerBootstrap bootstrap=new ServerBootstrap();//服务启动辅助类
        bootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)//设置通信所使用的通道类型

                .childHandler(new ChannelInitializer<NioSocketChannel> (){//设置业务逻辑处理器 这里的channel是客户端注册的channel

                    protected void initChannel(NioSocketChannel channel) throws Exception {
                        channel.pipeline().addLast(new StringDecoder()).addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                String respMsg="hello world 2! i'm netty!";
                                ByteBuf respBuffer = Unpooled.wrappedBuffer(respMsg.getBytes("utf-8"));
                                ChannelFuture f = ctx.channel().writeAndFlush(respBuffer);//类似java线程的future模式
                               // f.addListener(ChannelFutureListener.CLOSE);
                            }

                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

                                System.out.println(ctx.channel().getClass());
                                System.out.println(msg.getClass());
                                System.out.println(msg);
                                String respMsg="hello world! i'm netty!";
                                ByteBuf respBuffer = Unpooled.wrappedBuffer(respMsg.getBytes("utf-8"));
                                ChannelFuture f = ctx.channel().writeAndFlush(respBuffer);//类似java线程的future模式
//                                ctx.writeAndFlush(respBuffer);

                                //发送完消息需要关闭客户端channel
                                //上面发送消息的过程是一个异步的过程  所以直接采用 ctx.close()可能会导致消息未发送出去 而channel关闭
                                //使用监听器 待消息发送完毕 触发关闭 channel
                                f.addListener(ChannelFutureListener.CLOSE)
                                /*.addListeners(new ChannelFutureListener(){
                                    public void operationComplete(ChannelFuture channelFuture) throws Exception {
                                        channelFuture.channel().close();
                                    }
                                })*/;
                            }
                        });
                    }
                })
                .option(ChannelOption.SO_BACKLOG,1024)//设置TCP各种参数  TODO 有待研究tcp协议各种参数
                .childOption(ChannelOption.SO_KEEPALIVE,true);

        try {
            ChannelFuture f = bootstrap.bind(8888).sync();//服务器绑定
            f.channel().closeFuture().sync();//通道关闭
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //关闭所有服务线程
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }


    }
}
